// useMap3D.js
import * as Cesium from "cesium";
import { ElMessage } from 'element-plus';
import { ref, onMounted, onUnmounted, getCurrentInstance } from 'vue';

export function useMap3D() {
    // 状态管理
    const defaultAccessToken = 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJqdGkiOiJmNjk0OWE0My0wMzMwLTRjNTMtYmUyYS1lMzZiNTc1OTg0MjgiLCJpZCI6NTkxOTgsImlhdCI6MTYyMzg5ODgwMX0.Lv2oNmbHCD4Kuonq8-mehRrfknQX_npRIXNYmjjqRio';
    const tileModels = ref([]); // 3d倾斜模型数组
    const viewer = ref(undefined); // Cesium viewer实例
    const pickedObject = ref(null) // 添加 pickedObject
    const entitiesList = ref([]); // 存储所有加载的gltf显示的实体模型

    // 存储上一个选中的要素和原始颜色
    let highlightedEntity = null;
    let originalColor = null; // 存储原始颜色（Cesium.Color对象）

    // 初始化3D地图
    const init3DMap = () => {
        Cesium.Ion.defaultAccessToken = defaultAccessToken;
        viewer.value = new Cesium.Viewer('cesiumContainer', {
            terrain: null,
            // terrain: Cesium.Terrain.fromWorldTerrain({
            //     requestVertexNormals: false,
            //     requestWaterMask: false,
            // }),
            baseLayerPicker: false,
            geocoder: false,
            homeButton: false,
            sceneModePicker: false,
            navigationHelpButton: false,
            animation: false,
            timeline: false,
            fullscreenButton: false,
            vrButton: false,
            infoBox: false,
            selectionIndicator: true,
            scene3DOnly: true,
            shouldAnimate: true,
            useDefaultRenderLoop: true,
            targetFrameRate: 30,
            showRenderLoopErrors: false,
            automaticallyTrackDataSourceClocks: false,
            contextOptions: {
                webgl: {
                    powerPreference: 'high-performance',
                    antialias: false
                }
            },
            sceneMode: Cesium.SceneMode.SCENE3D,
            terrainExaggeration: 1.0,
            requestRenderMode: true,
            maximumRenderTimeChange: 0.0
        });

        // 性能优化设置
        viewer.value.scene.requestRenderMode = true;
        viewer.value.scene.debugShowFramesPerSecond = false;
        viewer.value.scene.requestRender();
        viewer.value.scene.postUpdate.addEventListener((event) => {
            if (event._performanceContainer) {
                event._performanceContainer.style.display = 'none';
            }
        });
        viewer.value._cesiumWidget._creditContainer.style.display = "none";
        viewer.value.scene.backgroundColor = new Cesium.Color(0, 0, 0, 0);
        viewer.value.scene.globe.baseColor = new Cesium.Color(0, 0, 0, 0);

        // 相机控制
        viewer.value.scene.screenSpaceCameraController.minimumZoomDistance = 20;
        viewer.value.scene.screenSpaceCameraController.maximumZoomDistance = 20000000;

        // 初始视角
        viewer.value.camera.setView({
            destination: Cesium.Cartesian3.fromDegrees(106.608276, 26.376567, 5000),
            endTransform: Cesium.Matrix4.IDENTITY,
        });

        // 启用深度检测，确保正确拾取模型
        viewer.value.scene.globe.depthTestAgainstTerrain = true;

        // 添加点击事件监听
        viewer.value.screenSpaceEventHandler.setInputAction((event) => {
            try {
                console.log("点击电机端")
                pickedObject.value = null
                var pickedFeature = viewer.value.scene.pick(event.position);
                // 移除之前的高亮
                removeHighlight();
                if (Cesium.defined(pickedFeature) && Cesium.defined(pickedFeature.id)) {
                    const entity = pickedFeature.id;

                    // 高亮当前选中的实体
                    highlightEntity(entity);


                    // 获取属性
                    const properties = entity.properties;

                    if (properties) {
                        pickedObject.value = {
                            modelRoomId: properties.modelRoomId.getValue(),
                            roomNumber: properties.roomNumber.getValue(),
                            floor: properties.floor.getValue(),
                            parkName: properties.parkName.getValue(),
                            parkNuilding: properties.parkNuilding.getValue(),
                            enterpriseName: properties.enterpriseName.getValue(),
                            area: properties.area.getValue(),
                            status: properties.status.getValue(),
                        }
                    }

                } else {
                    console.log("未点击到任何东西")
                }
            } catch (err) {
                console.log("点击报错", err)
            }

        }, Cesium.ScreenSpaceEventType.LEFT_CLICK)
        setBaseImg();
    };

    //---------------------------------------------------鼠标点击模型获取值开始----------------------------------------
    // 高亮实体函数
    function highlightEntity(entity) {
        if (!entity || !entity.model) return;

        // 移除之前的高亮
        removeHighlight();

        // 获取当前颜色：如果 model.color 不存在，则使用默认的白色
        let currentColor;
        if (entity.model.color) {
            // 如果 color 是一个 Property，尝试获取其值
            if (typeof entity.model.color.getValue === 'function') {
                currentColor = entity.model.color.getValue(Cesium.JulianDate.now());
            } else {
                // 如果直接是颜色值，则使用它
                currentColor = entity.model.color;
            }
        } else {
            // 如果没有设置颜色，使用默认的白色
            currentColor = Cesium.Color.WHITE;
        }

        // 保存原始颜色
        originalColor = Cesium.Color.clone(currentColor);

        // 设置高亮颜色（使用半透明红色）
        entity.model.color = new Cesium.ConstantProperty(
            Cesium.Color.YELLOW.withAlpha(0.7)  // 降低透明度让红色更明显
        );
        // 设置轮廓高亮
        // entity.model.silhouetteColor = new Cesium.ConstantProperty(Cesium.Color.RED);
        // entity.model.silhouetteSize = new Cesium.ConstantProperty(3.0); // 轮廓粗细

        // 记录当前高亮的实体
        highlightedEntity = entity;

        console.log('实体已高亮:', entity);
    }

    // 修复后的移除高亮函数
    function removeHighlight() {
        if (highlightedEntity && originalColor) {
            try {
                // 恢复原始颜色 - 使用 ConstantProperty 包装
                highlightedEntity.model.color = new Cesium.ConstantProperty(originalColor);
                // 移除轮廓高亮
                // highlightedEntity.model.silhouetteSize = new Cesium.ConstantProperty(0.0);
                console.log('高亮已移除，恢复原始颜色:', originalColor);
            } catch (error) {
                console.error('移除高亮时出错:', error);
            }

            // 重置变量
            highlightedEntity = null;
            originalColor = null;
        }
    }

    //---------------------------------------------------鼠标点击模型获取值结束----------------------------------------

    // 设置自定义DEM
    const setTerrain = async (url) => {
        if (!viewer.value) return;

        try {
            const terrainProvider = await Cesium.CesiumTerrainProvider.fromUrl(url, {
                minimumLevel: 0,
                maximumLevel: 8,
                requestWaterMask: false,
                requestVertexNormals: false
            });

            if (terrainProvider) {
                viewer.value.terrainProvider = terrainProvider; // 正确的方式
            }
        } catch (error) {
            ElMessage.error('地形加载失败: ' + error.message);
        }
    };

    // 添加底图
    const setBaseImg = () => {
        if (!viewer.value) return;

        const token = 'fe2c0dc9e1334708ac9a1d987fa369ad';
        const tdtUrl = `https://t{s}.tianditu.gov.cn/`;
        const subdomains = ['0', '1', '2', '3', '4', '5', '6', '7'];

        const gzWMTS = new Cesium.UrlTemplateImageryProvider({
            url: tdtUrl + 'DataServer?T=img_w&x={x}&y={y}&l={z}&tk=' + token,
            subdomains: subdomains,
            tilingScheme: new Cesium.WebMercatorTilingScheme(),
            maximumLevel: 16
        });

        const zjWMTS = new Cesium.UrlTemplateImageryProvider({
            url: tdtUrl + 'DataServer?T=cia_w&x={x}&y={y}&l={z}&tk=' + token,
            subdomains: subdomains,
            tilingScheme: new Cesium.WebMercatorTilingScheme(),
            maximumLevel: 16
        });

        viewer.value.imageryLayers.addImageryProvider(gzWMTS);
        viewer.value.imageryLayers.addImageryProvider(zjWMTS);
    };

    // 设置视图范围
    const setCenterExtent = (extent) => {
        if (!viewer.value || !extent) return;

        const params = {
            lon_min: extent[0],
            lat_min: extent[1],
            lon_max: extent[2],
            lat_max: extent[3]
        };

        const exet = new Cesium.Cartesian3.fromDegrees(params.lon_min, params.lat_min, 600);
        viewer.value.camera.flyTo({
            destination: exet,
            duration: 5,
            easingFunction: Cesium.EasingFunction.LINEAR,
            orientation: {
                heading: Cesium.Math.toRadians(0.0),
                pitch: Cesium.Math.toRadians(-90.0),
                roll: 0.0
            }
        });
    };

    // 添加倾斜模型
    const set3Dtile = async (url, id, loading, height) => {
        if (!viewer.value) return false;
        try {
            // 先移除同名模型
            await remove3Dtitle(id);
            const tilesetModel = await Cesium.Cesium3DTileset.fromUrl(url, {


                // 核心性能优化参数
                // maximumScreenSpaceError: 2, // 提高容错率，显著提升性能
                // maximumNumberOfLoadedTiles: 400, // 大幅减少同时加载的瓦片数量
                // skipLevelOfDetail: true, // 启用LOD跳过，重要优化
                // skipScreenSpaceErrorFactor: 16, // LOD跳过因子
                // // skipLevels: 1, // 跳过的级别数
                // minimumLevel: 2,
                // maximumLevel: 8,

                // // 预加载优化
                // loadSiblings: false, // 关闭兄弟节点预加载
                // preloadAncestors: false, // 关闭祖先节点预加载
                // preloadSiblings: false, // 关闭兄弟节点预加载

                // // 剔除优化
                // cullWithChildrenBounds: true, // 启用子边界剔除
                // cullRequestsWhileMoving: true, // 移动时暂停请求
                // cullRequestsWhileMovingMultiplier: 10.0, // 移动时请求乘数

                // // 动态加载控制
                // dynamicScreenSpaceError: true, // 启用动态误差调整
                // dynamicScreenSpaceErrorDensity: 0.00278,
                // dynamicScreenSpaceErrorFactor: 8.0, // 提高因子
                // dynamicScreenSpaceErrorHeightFalloff: 0.5,

                // // 其他优化
                // immediatelyLoadDesiredLevelOfDetail: false, // 关闭立即加载目标LOD
                // loadSkipLevels: true, // 启用跳过级别加载
                // // baseScreenSpaceError: 1024, // 提高基础误差
                // // maximumMemoryUsage: 512, // 限制内存使用(MB)

                // // 网络优化
                // preferLeaves: false, // 优先加载父节点
                // maximumSimultaneousTileLoads: 20, // 限制并发加载数
                // progressiveResolutionHeightFraction: 0.5, // 渐进式分辨率
                // 尝试贴地
                clampToGround: true,

                maximumScreenSpaceError: 2, // 适当提高容错，减少初始加载压力
                maximumNumberOfLoadedTiles: 500, // 限制同时加载的瓦片数量
                baseScreenSpaceError: 5.0,
                minimumLevel: 2, // 强制从第2级开始加载（级别越小精度越高）
                maximumLevel: 4, // 限制最大级别，避免过度加载
                msaaSamples: 4, // 4x抗锯齿，值越高越平滑（影响性能）
                priority: 200,
                loadSiblings: true,
                cullWithChildrenBounds: true,
                preloadAncestors: true,
                preloadSiblings: true,
                immediatelyLoadDesiredLevelOfDetail: true,//是否立即加载目标 LOD 层级（可能影响流畅度但提高精度）
                dynamicScreenSpaceError: false,// 启用动态屏幕空间误差调整:cite[1]
                dynamicScreenSpaceErrorDensity: 0.00278,// 调整动态误差密度:cite[1]
                dynamicScreenSpaceErrorFactor: 4.0,// 动态误差因子:cite[1]
                dynamicScreenSpaceErrorHeightFalloff: 0.25,// 高度衰减系数:cite[1]
            });
            await tilesetModel.readyPromise;
            viewer.value.scene.primitives.add(tilesetModel);
            if (height >= 0) {
                //贴地显示
                adjustHeightPrecise(tilesetModel, height)
            }

            let pitch = 1.5
            let range = -0.3
            //单独给六盘水工业园区增加视角
            if (url.includes('lps')) {
                pitch = 0
                range = -0.3
            }

            flyTo3Dtiles(tilesetModel, pitch, range);

            tileModels.value.push({
                id: id,
                clickHandler: null,
                tileset: tilesetModel
            });

            console.log('模型加载成功');
            return true;
        } catch (err) {
            console.log(err)
            ElMessage.error('模型加载失败: ' + err.message);
            return false;
        } finally {
            if (loading) {
                loading.close()
            }
        }
    };


    //精确的调整（保持经纬度不变）
    const adjustHeightPrecise = (tileset, targetHeight) => {
        const boundingSphere = tileset.boundingSphere;
        const center = boundingSphere.center;

        // 转换为地理坐标
        const cartographic = Cesium.Cartographic.fromCartesian(center);

        // 计算高度差
        const heightDifference = targetHeight - cartographic.height;

        // 获取地表法线
        const surfaceNormal = Cesium.Ellipsoid.WGS84.geodeticSurfaceNormal(center);

        // 沿法线方向平移
        const translation = Cesium.Cartesian3.multiplyByScalar(
            surfaceNormal,
            heightDifference,
            new Cesium.Cartesian3()
        );

        tileset.modelMatrix = Cesium.Matrix4.fromTranslation(translation);
    };




    // 缩放到模型
    const flyTo3Dtiles = (tileset, pitch, range) => {
        if (!viewer.value) return;

        viewer.value.flyTo(tileset, {
            offset: new Cesium.HeadingPitchRange(
                pitch == null ? 1.5 : pitch,//相机的方位角（偏航角），以弧度表示,默认值: 0.0,0 = 北, π/2 = 东, π = 南, 3π/2 = 西
                range == null ? -0.3 : range,//相机的俯仰角，以弧度表示,0 = 水平, -π/2 = 垂直向下, π/2 = 垂直向上
                tileset.boundingSphere.radius //相机与目标中心点的距离,默认值: 目标边界球半径
            ),
            duration: 3,//飞行动画的持续时间，以秒为单位
        });
    };

    // 移除模型
    const remove3Dtitle = async (targetId) => {
        if (!viewer.value) return false;

        try {
            const index = tileModels.value.findIndex(model => model.id === targetId);
            if (index === -1) return true;

            const modelInfo = tileModels.value[index];
            const { tileset } = modelInfo;

            tileset.show = false;
            if (viewer.value.scene.primitives.contains(tileset)) {
                viewer.value.scene.primitives.remove(tileset);
            }

            safeDestroyTileset(tileset);
            tileModels.value.splice(index, 1);
            viewer.value.scene.requestRender();
            console.log("模型移除成功")
            return true;
        } catch (e) {
            ElMessage.error('模型移除失败: ' + e.message);
            return false;
        }
    };

    // 安全销毁模型
    const safeDestroyTileset = (tileset) => {
        if (!tileset || tileset.isDestroyed()) return;
        try {
            if (tileset.cancelPendingRequests) {
                tileset.cancelPendingRequests();
            }

            if (tileset.root) {
                destroyTile(tileset.root);
            }

            if (!tileset.isDestroyed()) {
                tileset.destroy();
            }
        } catch (e) {
            console.warn('销毁对象时出错:', e);
        }
    };

    // 递归销毁瓦片
    const destroyTile = (tile) => {
        if (!tile) return;

        if (tile.children && tile.children.length > 0) {
            tile.children.forEach(child => destroyTile(child));
        }

        if (tile.content && !tile.content.isDestroyed()) {
            tile.content.destroy();
        }
    };

    // 缩放至指定模型
    const zoomModel = (layerId) => {
        if (!viewer.value) return;
        const index = tileModels.value.findIndex(model => model.id === layerId);
        if (index === -1) return;

        const { tileset } = tileModels.value[index];
        flyTo3Dtiles(tileset);
    };

    // 加载GLTF模型
    const addGltf = async (item) => {
        try {
            if (entitiesList.value.length == 173) {
                return
            }
            var position = Cesium.Cartesian3.fromDegrees(item.longitude, item.latitude, item.altitude);

            // 创建实体并设置位置
            const entity = viewer.value.entities.add({
                id: item.modelRoomId,
                model: {
                    uri: import.meta.env.VITE_BASE_MODEL_URL + "/" + item.gltfUrl,
                    scale: 1.0,
                    heightReference: Cesium.HeightReference.NONE,
                    // 颜色相关配置
                    colorBlendMode: Cesium.ColorBlendMode.MIX,
                    colorBlendAmount: 0.7, // 0-1，0表示原色，1表示完全使用color颜色
                    silhouetteColor: Cesium.Color.YELLOW, // 轮廓颜色
                    silhouetteSize: 1 // 轮廓大小
                },
                show: false,
                // 设置自定义属性
                properties: {
                    modelRoomId: item.modelRoomId,
                    roomNumber: item.roomNumber,
                    floor: item.floor,
                    parkName: item.parkName,
                    parkId: item.parkId,
                    parkNuilding: item.parkNuilding,
                    remark: item.remark,
                    enterpriseName: item.enterpriseName,
                    area: item.area,
                    status: item.status,
                }
            });
            if (item.status) {
                entity.model.color = Cesium.Color.RED;
            } else {
                entity.model.color = Cesium.Color.GREEN;
            }
            entity.position = position
            var hpr = new Cesium.HeadingPitchRoll(
                Cesium.Math.toRadians(90),
                Cesium.Math.toRadians(0),
                Cesium.Math.toRadians(0)
            );
            var orientation = Cesium.Transforms.headingPitchRollQuaternion(position, hpr);
            entity.orientation = orientation;

            // 保存实体引用到数组（关键：后续移除依赖此引用）
            entitiesList.value.push({
                model: entity,
                floor: item.floor
            });

        } catch (error) {
            console.error('加载GLTF数据失败：', error);
        }
    };

    const removeGltf = async (floor) => {
        entitiesList.value.forEach(model => {
            // viewer.value.entities.remove(entity); // 逐个移除
            if (floor) {
                if (floor == -1) {
                    model.model.show = true
                } else if (floor == model.floor) {
                    model.model.show = true
                } else {
                    model.model.show = false
                }
            } else {
                model.model.show = false
            }
        });
    }

    // 组件挂载时初始化地图
    onMounted(() => {
        init3DMap();
    });

    // 组件卸载时清理资源
    onUnmounted(() => {
        if (viewer.value) {
            try {
                // 简化的清理流程
                // 1. 移除所有事件监听器
                if (viewer.value.screenSpaceEventHandler) {
                    viewer.value.screenSpaceEventHandler.removeInputAction(Cesium.ScreenSpaceEventType.LEFT_CLICK);
                }

                // 2. 清除所有模型
                tileModels.value.forEach(model => {
                    try {
                        if (model.tileset && viewer.value.scene.primitives.contains(model.tileset)) {
                            viewer.value.scene.primitives.remove(model.tileset);
                        }
                    } catch (e) {
                        console.warn('移除tileset时出错:', e);
                    }
                });
                tileModels.value = [];

                // 3. 清除所有实体
                viewer.value.entities.removeAll();
                entitiesList.value = [];

                // 4. 销毁viewer
                if (!viewer.value.isDestroyed()) {
                    viewer.value.destroy();
                }
                viewer.value = undefined;

            } catch (error) {
                console.error('清理Cesium资源时出错:', error);
                // 强制清空引用
                viewer.value = undefined;
                tileModels.value = [];
                entitiesList.value = [];
            }
        }
    });

    // 暴露公共方法和状态
    return {
        viewer,
        tileModels,
        setTerrain,
        setBaseImg,
        setCenterExtent,
        set3Dtile,
        remove3Dtitle,
        zoomModel,
        addGltf,
        removeGltf,
        pickedObject, // 返回 pickedObject
    };
}